﻿using CaseManagerLibrary.Http;
using CaseManagerLibrary.Log;
using CaseManagerLibrary.Models;
//using NetSDKCS;
using Newtonsoft.Json;
using PSDClientService.SystemSettings;
using PSDLib;
using PSDLib.Download;
using PSDLib.Models;
using PSDLib.Protocols;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PSDClientService.Download
{
    public delegate void StartDownloadEventHandler();
    public delegate void StopDownloadEventHandler();
    public delegate void DownloadStateChangedEventHandler(string id, int state);
    public delegate void CreateDownloadEventHandler(dl_files file);
    public delegate void CreateTaskEventHandler(dl_task task, List<dl_task_channel> channels);

    public class DailyDownloadManager
    {
        private DownloadContext context;

        //private fDisConnectCallBack m_DisConnectCallBack;
        //private fHaveReConnectCallBack m_ReConnectCallBack;
        //public NET_DEVICEINFO_Ex m_DeviceInfo;
        //public IntPtr m_LoginID;

        public event StartDownloadEventHandler OnStartDownload;
        public event StopDownloadEventHandler OnStopDownload;
        public event CreateDownloadEventHandler OnCreateDownload;
        public event UpdateDownloadProgressEventHandler OnUpdateDownloadProgress;
        public event FileDownloadCompletedEventHandler OnFileDownloadSuccess;
        public event FileDownloadCompletedEventHandler OnFileDownloadFail;
        public event DownloadStateChangedEventHandler OnDownloadTaskStateChanged;
        public event DownloadStateChangedEventHandler OnDownloadChannelStateChanged;

        private Thread refreshTaskThread = null;


        public event CreateTaskEventHandler OnCreateTask;

        /// <summary>
        /// 下载任务集合
        /// </summary>
        public DownloadTaskList DownloadTaskList { get; set; }
        private static object lock_DownloadTaskList = new object();

        /// <summary>
        /// 下载任务等待队列
        /// </summary>
        public List<dl_files> DownloadWaitingList { get; set; }
        private static object lock_DownloadWaitingList = new object();
        public List<IDownloadServer> DownloadServerList { get; set; }
        public List<IDownloader> DownloaderList { get; set; }
        private int downloaderCount = 0;
        private static object lock_DownloaderList = new object();

        public List<dl_files> DownloadingFiles { get; set; }
        public List<dl_room_config> RoomConfigList { get; set; }
        public List<dl_route_config> RouteConfigList { get; set; }
        //public List<dl_camera> CameraList { get; set; }

        private System.Timers.Timer downloadTimer;


        public DailyDownloadManager(DownloadContext ctx)
        {
            DownloadTaskList = new DownloadTaskList();
            //DownloadServerList = new List<dl_server_config>();
            RoomConfigList = new List<dl_room_config>();
            RouteConfigList = new List<dl_route_config>();
            //CameraList = new List<dl_camera>();
            DownloaderList = new List<IDownloader>();
            DownloadWaitingList = new List<dl_files>();
            DownloadingFiles = new List<dl_files>();
            DownloadServerList = new List<IDownloadServer>();

            context = ctx;

            //m_DisConnectCallBack = new fDisConnectCallBack(DisConnectCallBack);
            //m_ReConnectCallBack = new fHaveReConnectCallBack(ReConnectCallBack);

            downloadTimer = new System.Timers.Timer();
            downloadTimer.Enabled = false;
            downloadTimer.Interval = 5000;
            downloadTimer.Elapsed += DownloadTimer_Elapsed;
        }

        #region Task Manager
        /// <summary>
        /// 开始刷新当前设备任务
        /// </summary>
        public void LoopRefreshTaskInfo()
        {
            refreshTaskThread = new Thread(new ThreadStart(delegate ()
            {
                while (context.Downloading)
                {
                    RefreshTaskInfo();

                    Thread.Sleep(1000 * 60);
                }
            }));

            refreshTaskThread.Start();
        }



        /// <summary>
        /// 刷新当前设备的下载任务信息
        /// </summary>
        /// <returns></returns>
        public HResult<List<dl_task>> RefreshTaskInfo()
        {
            HResult<List<dl_task>> result_task = null;

            lock (lock_DownloadTaskList)
            {
                try
                {
                    result_task = HttpHelper.Get<HResult<List<dl_task>>>(AppSettings.Setting.API.GetDownloadingTaskList + "?deviceId=" + context.UUID);

                    if (result_task.success)
                    {
                        //移除已被取消的DownloadTask
                        for (int i = DownloadTaskList.Count - 1; i >= 0; i--)
                        {
                            if (result_task.data.Where(t => t.id == DownloadTaskList[i].Task.id).FirstOrDefault() == null)
                            {
                                DownloadTaskList.RemoveAt(i);
                            }
                        }

                        //添加新的DownloadTask
                        for (int i = 0; i < result_task.data.Count; i++)
                        {
                            if (DownloadTaskList.Where(t => t.Task.id == result_task.data[i].id).FirstOrDefault() == null)
                            {
                                var dt = new DownloadTask();
                                dt = new DownloadTask();
                                dt.Task = result_task.data[i];

                                var result_channel = HttpHelper.Get<HResult<List<dl_task_channel>>>(AppSettings.Setting.API.GetChannelList + "?taskId=" + result_task.data[i].id);

                                if (result_channel.success)
                                {
                                    dt.ChannelList = result_channel.data;
                                }

                                DownloadTaskList.Add(dt);

                                OnCreateTask?.Invoke(dt.Task, dt.ChannelList);
                            }
                        }

                        //DownloadTaskList.Clear();
                        //foreach (var task in result_task.data)
                        //{
                        //    var dt = new DownloadTask();
                        //    dt = new DownloadTask();
                        //    dt.Task = task;

                        //    var result_channel = HttpHelper.Get<HResult<List<dl_task_channel>>>(AppSettings.Setting.API.GetChannelList + "?taskId=" + task.id);
                        //    List<dl_task_channel> channels = null;

                        //    if (result_channel.success)
                        //    {
                        //        dt.ChannelList = result_channel.data;
                        //    }

                        //    DownloadTaskList.Add(dt);

                        //    OnCreateTask?.Invoke(task, channels);
                        //}
                    }
                }
                catch (Exception ex)
                {
                    context.Logger.Error("RefreshTaskInfo - " + ex.Message + (ex.InnerException == null ? "" : ex.InnerException.Message));
                }
            }

            return result_task;
        }
        #endregion

        private void DownloadTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //检测最大下载进程
            lock (lock_DownloaderList)
            {
                if (downloaderCount >= AppSettings.Setting.MaxDownloadProcess)
                {
                    return;
                }
                else
                {
                    downloaderCount += 1;
                }
            }

            DoWork();

            context.ClientContext.MessageManager.SendToListener(new KeepAliveMessage());
        }

        public bool Init()
        {
            bool success = false;

            if (context.Device != null)
            {
                //获取视频存储设备信息
                GetDownloadServerList();
                if (DownloadServerList.Count == 0)
                {
                    context.Logger.Error("未配置下载服务器信息");
                    return success;
                }

                //获取下载通道信息
                GetRoomConfigList();
                if (RoomConfigList.Count == 0)
                {
                    context.Logger.Error("未配置房间下载通道信息");
                    return success;
                }

                //获取路径规划下载通道
                GetRouteConfigList();
                if (RouteConfigList.Count == 0)
                {
                    context.Logger.Error("未配置路径规划下载通道");
                    //return success;
                }

                ////获取摄像机信息
                //GetCameraList();
                //if (CameraList.Count == 0)
                //{
                //    return success;
                //}

                AppSettings.Setting.MaxDownloadProcess = this.context.Device.max_download_process;

                success = true;
            }

            return success;
        }

        private void DownloadServer_OnReConnect(object sender, EventArgs e)
        {
            StartDownload();
        }

        private void DownloadServer_OnDisConnect(object sender, EventArgs e)
        {
            StopDownload();
        }

        public void Cleanup()
        {
            //if (DownloadServer != null)
            //{
            //    DownloadServer.Cleanup();
            //}

            foreach (var server in DownloadServerList)
            {
                if (server.Online)
                {
                    server.Logout();
                }

                server.Cleanup();
            }
        }

        ///// <summary>
        ///// 初始化下载助手，登录大华存储设备、启动tcp消息服务
        ///// </summary>
        ///// <returns></returns>
        //public bool LoginDownloadServer()
        //{
        //    //return DownloadServer.Login();
        //    foreach (var server in DownloadServerSet)
        //    {
        //        if (server.Online)
        //        {
        //            server.Logout
        //        }
        //    }

        //}

        ///// <summary>
        ///// 登出下载服务器，停止tcp消息监听
        ///// </summary>
        //public void LogoutDownloadServer()
        //{
        //    DownloadServer.Logout();
        //}

        /// <summary>
        /// 获取大华存储设备信息
        /// </summary>
        public void GetDownloadServerList()
        {
            var result_server = HttpHelper.Get<HResult<List<dl_server_config>>>(AppSettings.Setting.API.GetDownloadServerConfig);

            if (result_server.success)
            {
                context.Logger.Info("获取存储设备信息成功");
                //DownloadServerList = result_server.data;

                foreach (var server in result_server.data)
                {
                    var downloadServer = DownloadServerFactory.Create(server.storage_server_type);
                    downloadServer.OnDisConnect += DownloadServer_OnDisConnect;
                    downloadServer.OnReConnect += DownloadServer_OnReConnect;

                    downloadServer.Logger = context.Logger;

                    downloadServer.ID = server.id;
                    downloadServer.Name = server.storage_server_name;
                    downloadServer.ServerIP = server.storage_server_ip;
                    downloadServer.ServerPort = server.storage_server_port;
                    downloadServer.ServerUser = server.storage_server_user;
                    downloadServer.ServerPassword = server.storage_server_password;

                    if (downloadServer.Init())
                    {
                        DownloadServerList.Add(downloadServer);
                    }
                }
            }
            else
            {
                context.Logger.Error("获取存储设备信息失败：" + result_server.message);
            }
        }

        /// <summary>
        /// 获取下载通道信息
        /// </summary>
        public void GetRoomConfigList()
        {
            var result_room = HttpHelper.Get<HResult<List<dl_room_config>>>(AppSettings.Setting.API.GetAllRoomConfig);

            if (result_room.success)
            {
                context.Logger.Info("获取下载通道信息成功");
                RoomConfigList = result_room.data;
            }
            else
            {
                context.Logger.Error("获取下载通道信息失败：" + result_room.message);
            }
        }

        public void GetRouteConfigList()
        {
            var result_route = HttpHelper.Get<HResult<List<dl_route_config>>>(AppSettings.Setting.API.GetAllRouteConfig);

            if (result_route.success)
            {
                context.Logger.Info("获取路径下载通道信息成功");
                RouteConfigList = result_route.data;
            }
            else
            {
                context.Logger.Error("获取路径下载通道信息失败：" + result_route.message);
            }
        }

        //public void GetCameraList()
        //{
        //    var result_camera = HttpHelper.Get<HResult<List<dl_camera>>>(AppSettings.Setting.API.GetAllCamera);

        //    if (result_camera.success)
        //    {
        //        context.Logger.Info("获取摄像机信息成功");
        //        CameraList = result_camera.data;
        //    }
        //    else
        //    {
        //        context.Logger.Error("获取摄像机信息失败：" + result_camera.message);
        //    }
        //}

        /// <summary>
        /// 得到一个下载服务器配置
        /// </summary>
        /// <param name="serverId"></param>
        /// <returns></returns>
        //public dl_server_config GetServerConfig(string serverId)
        //{
        //    return DownloadServerList.Where(t => t.id == serverId).FirstOrDefault();
        //}

        /// <summary>
        /// 开始下载
        /// </summary>
        public void StartDownload()
        {
            lock (context.lock_Downloading)
            {
                try
                {
                    context.Logger.Info("正在启动下载");

                    context.Downloading = true;

                    downloaderCount = 0;

                    ResetDownloadingFiles();

                    GetDownloadWaitingFiles();

                    downloadTimer.Enabled = true;

                    LoopRefreshTaskInfo();

                    OnStartDownload?.Invoke();
                }
                catch (Exception ex)
                {
                    context.Logger.Error("StartDownload 失败：" + ex.Message);
                }
            }
        }

        /// <summary>
        /// 停止下载
        /// </summary>
        public void StopDownload()
        {
            lock (context.lock_Downloading)
            {
                try
                {
                    context.Logger.Info("正在停止下载");

                    downloadTimer.Enabled = false;

                    context.Downloading = false;

                    for (int i = DownloaderList.Count - 1; i >= 0; i--)
                    {
                        DownloaderList[i].Stop();

                        DownloaderList.RemoveAt(i);
                    }

                    DownloadingFiles.Clear();
                    DownloadTaskList.Clear();
                    downloaderCount = 0;

                    try
                    {
                        refreshTaskThread.Abort();
                    }
                    catch { }

                    OnStopDownload?.Invoke();
                }
                catch (Exception ex)
                {
                    context.Logger.Error("StopDownload 失败：" + ex.Message);
                }
            }
        }

        public void ReStartDownload()
        {
            StopDownload();

            StartDownload();
        }

        public void ResetDownloadingFiles()
        {
            Dictionary<string, string> data = new Dictionary<string, string>();
            data.Add("deviceId", this.context.Device.id);
            var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.ResetDownloadingFiles, data);

            if (result.success)
            {
                context.Logger.Log("重置未下载完成文件");
            }
        }

        /// <summary>
        /// 处理未完成的文件下载任务
        /// </summary>
        public void GetDownloadWaitingFiles()
        {
            var result_file = HttpHelper.Get<HResult<List<dl_files>>>(AppSettings.Setting.API.GetDownloadWaitingFiles + "?deviceId=" + this.context.Device.id);

            if (result_file.success)
            {
                if (result_file.data != null)
                {
                    context.Logger.Info("获取等待下载文件队列：" + result_file.data.Count + "个文件");

                    lock (lock_DownloadWaitingList)
                    {
                        DownloadWaitingList.Clear();

                        for (int i = 0; i < result_file.data.Count; i++)
                        {
                            DownloadWaitingList.Add(result_file.data[i]);

                            context.Logger.Text($"{i + 1}. " + result_file.data[i].file_name);
                        }
                    }
                }
            }
            else
            {
                context.Logger.Error("获取待下载文件队列失败：" + result_file.message);
            }
        }

        /// <summary>
        /// 执行文件下载过程,
        /// 
        /// 循环下载任务的方法，必须放在主线程中通过窗体上的Timer控件来调用，否则会和大华下载SDK的内部线程管理代码冲突，导致SDK内部线程被挂起，无法退出
        /// </summary>
        public void DoWork()
        {
            bool downloaderCreated = false;

            //检测可用存储
            if (!context.ClientContext.DeviceManager.CheckCurrentStorage())
            {
                return;
            }

            //检测最大下载进程
            //int d_count = 0;
            //lock (lock_DownloaderList)
            //{
            //    d_count = DownloaderList.Count;
            //}

            //if (d_count >= AppSettings.Setting.MaxDownloadProcess)
            //{
            //    return;
            //}

            //检测下载服务状态
            bool downloading = false;
            lock (context.lock_Downloading)
            {
                downloading = context.Downloading;
            }
            if (!downloading || context.Closing)
            {
                context.Logger.Info("DoWork - downloading=false and context.Closing=true DoWork方法停止执行");
                return;
            }

            //如果存在上次未完成的下载，则先执行下载等待队列的内容
            dl_files waitingFile = null;
            lock (lock_DownloadWaitingList)
            {
                if (DownloadWaitingList.Count > 0)
                {
                    waitingFile = DownloadWaitingList[0];
                }
            }

            if (waitingFile != null)
            {
                //等待中的任务
                downloaderCreated = CreateDownload(waitingFile).success;
            }
            else
            {
                //创建新任务
                lock (lock_DownloadTaskList)
                {
                    try
                    {
                        var downloadTask = DownloadTaskList.GetCurrentDownloadTask();

                        if (downloadTask != null)
                        {
                            if (downloadTask.Task.download_state == (int)DownloadTaskSate.开始下载)
                            {
                                bool ignoreTime = false;

                                //得到当前任务的下载通道，存在多个下载通道的时候，根据通道顺序，依次循环开始下载
                                var channel = downloadTask.GetCurrentChannel();

                                if (channel != null && channel.download_state == (int)DownloadChanelState.正在下载)
                                {
                                    //创建该下载通道的下一个文件
                                    downloaderCreated = CreateNextDownload(channel.id, ignoreTime).success;
                                }
                                //将下载序列转移到该任务的下一个通道
                                downloadTask.MoveToNextChannel();
                            }
                            //将下载序列转移到下一个任务
                            DownloadTaskList.MoveToNextTask();
                        }
                    }
                    catch (Exception ex)
                    {
                        context.Logger.Error("DoWork - " + ex.Message + (ex.InnerException == null ? "" : ex.InnerException.Message));
                    }
                }
            }

            if (!downloaderCreated)
            {
                lock (lock_DownloaderList)
                {
                    downloaderCount -= 1;

                    if (downloaderCount < 0)
                    {
                        downloaderCount = 0;
                    }
                }

                if (downloaderCount == 0)
                {
                    DownloadServerList.ForEach(t =>
                    {
                        if (t.Online)
                        {
                            t.Logout();
                        }
                    });
                }
            }
        }

        /// <summary>
        /// 创建指定通道的下一个下载进程
        /// </summary>
        /// <param name="channelId"></param>
        /// <param name="ignoreTime"></param>
        /// <returns></returns>
        public HResult<dl_files> CreateNextDownload(string channelId, bool ignoreTime)
        {
            //在服务端创建下一个要下载的文件信息，记录到数据库，并返回文件信息
            string url = AppSettings.Setting.API.GetNextDownloadFile + "?channelId=" + channelId + "&ignoreTime=" + (ignoreTime ? 1 : 0);
            var result = HttpHelper.Get<HResult<dl_files>>(url);

            if (result.success)
            {
                //根据创建的文件信息开始下载
                var ret = CreateDownload(result.data);

                result.success = ret.success;
                result.message = ret.message;
            }
            else
            {
                context.Logger.Info("DoWork - GetNextDownloadFile - " + result.message);
            }

            return result;
        }

        public IDownloadServer GetDownloadServer(dl_files file)
        {
            IDownloadServer dlServer = null;

            var task = DownloadTaskList.Where(t => t.Task.id == file.dl_task_id).FirstOrDefault();

            if (task != null)
            {
                //if (task.Task.task_type == Convert.ToInt32(DownloadTaskCreateType.常规Routine)
                //    || task.Task.task_type == Convert.ToInt32(DownloadTaskCreateType.自定义时段)
                //    || task.Task.task_type == Convert.ToInt32(DownloadTaskCreateType.谈话Talk))
                //{
                //    var roomConfig = RoomConfigList.Where(t => t.room_num == file.room_num && t.channel_name == file.channel_name).FirstOrDefault();

                //    if (roomConfig != null)
                //    {
                //        dlServer = DownloadServerList.Where(t => t.ID == roomConfig.server_id).FirstOrDefault();
                //    }
                //}
                //else if (task.Task.task_type == Convert.ToInt32(DownloadTaskCreateType.摄像机SD卡))
                //{
                //    var task_channel = task.ChannelList.Where(t => t.id == file.dl_task_channel_id).FirstOrDefault();

                //    if (task_channel != null)
                //    {
                //        dlServer = DownloadServerList.Where(t => t.ID == task_channel.server_id).FirstOrDefault();
                //    }
                //}
                //else
                //{
                //    var routeConfig = RouteConfigList.Where(t => t.route_id == task.Task.route_id && t.channel_id == file.channel_id).FirstOrDefault();

                //    if (routeConfig != null)
                //    {
                //        dlServer = DownloadServerList.Where(t => t.ID == routeConfig.server_id).FirstOrDefault();
                //    }
                //}

                var task_channel = task.ChannelList.Where(t => t.id == file.dl_task_channel_id).FirstOrDefault();

                if (task_channel != null)
                {
                    dlServer = DownloadServerList.Where(t => t.ID == task_channel.server_id).FirstOrDefault();
                }
            }

            return dlServer;
        }
        /// <summary>
        /// 根据下载内容创建一个下载进程
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public HResult CreateDownload(dl_files file)
        {
            HResult result = null;

            var dlServer = GetDownloadServer(file);

            if (dlServer != null)
            {
                if (!dlServer.Online)
                {
                    if (dlServer.Login())
                    {
                        context.Logger.Info("登录下载服务器设备成功：" + dlServer.Name + " " + dlServer.ServerIP + ":" + dlServer.ServerPort);
                    }
                    else
                    {
                        context.Logger.Error("登录当前下载服务器设备失败：" + dlServer.Name + " " + dlServer.GetLastError());
                    }
                }

                lock (lock_DownloadWaitingList)
                {
                    var f = DownloadWaitingList.Where(t => t.id == file.id).FirstOrDefault();
                    if (f != null)
                    {
                        DownloadWaitingList.Remove(f);
                    }
                }

                if (dlServer.Online)
                {
                    //lock (DownloadServiceContext.lock_Progressing)
                    //{
                    context.Logger.Info("创建下载进程：" + System.IO.Path.Combine(file.file_path, file.file_name));
                    //}

                    try
                    {
                        var downloader = dlServer.CreateDownload(file);

                        downloader.UpdateDownloadProgress += Downloader_UpdateDownloadProgress;
                        downloader.FileDownloadSuccess += Downloader_FileDownloadSuccess;
                        downloader.FileDownloadFail += Downloader_FileDownloadFail;

                        lock (lock_DownloaderList)
                        {
                            this.DownloaderList.Add(downloader);
                        }

                        result = RunDownload(downloader, file);
                    }
                    catch (Exception ex)
                    {
                        result = new HResult() { success = false, message = ex.Message + (ex.InnerException == null ? "" : ex.InnerException.Message) };
                    }
                }
                else
                {
                    result = new HResult() { success = false, message = "未能连接下载服务器：" + dlServer.Name + " " + dlServer.ServerIP + ":" + dlServer.ServerPort };
                }
            }
            else
            {
                result = new HResult() { success = false, message = "未找到对应的下载服务器，filename=" + file.file_name };
            }

            if (!result.success)
            {
                file.state = 2;
                file.dl_end_time = DateTime.Now;
                file.error_log = result.message;
                var ret = HttpHelper.Post<HResult>(AppSettings.Setting.API.DownloadFail, JsonConvert.SerializeObject(file));

                context.Logger.Error("CreateDownload Error: " + result.message);
            }

            return result;
        }

        private HResult RunDownload(IDownloader downloader, dl_files file)
        {
            HResult result = null;

            if (downloader == null)
            {
                result = new HResult() { success = false, message = "下载进程为空" };
                return result;
            }

            if (file == null)
            {
                result = new HResult() { success = false, message = "下载文件为空" };
                return result;
            }

            if (context.RunAsService)
            {
                context.Logger.Log("开始下载文件：" + file.file_name);
            }
            else
            {
                //lock (DownloadServiceContext.lock_Progressing)
                //{
                context.Logger.NewLine();

                downloader.ProgressBar = new ConsoleProgressBar(Console.CursorLeft, Console.CursorTop, 50, ConsoleProgressBarType.Character);

                context.Logger.Top += 1;
                //}
            }

            result = downloader.Download(file);

            if (result.success)
            {
                //DownloadFailList.Remove(file);
                DownloadingFiles.Add(file);

                //context.Logger.Log("开始下载文件：" + file.file_name);

                var ret = HttpHelper.Post<HResult>(AppSettings.Setting.API.StartDownloadFile,
                    new Dictionary<string, string> {
                        { "fileId", file.id}
                    });

                //触发创建事件，在FrmMain上更新UI，并创建下载组件
                OnCreateDownload?.Invoke(file);
            }
            else
            {
                context.Logger.Error("创建下载进程失败：" + file.file_name + " - " + result.message);
            }

            return result;
        }

        //private void Downloader_ResetSession(IDownloader downloader, dl_files file)
        //{
        //context.Logger.Log("下载服务器Session过期，尝试自动重新登录");

        //StopDownload();

        //if (DownloadServer.ReLogin())
        //{
        //    context.Logger.Log("自动重新登录下载服务器成功");

        //    StartDownload();
        //    //DownloadServer.ResetSessionInfo(downloader);

        //    //RunDownload(downloader, file);
        //}
        //else
        //{
        //    context.Logger.Error("自动重新登录下载服务器失败：" + DownloadServer.GetLastError());

        //    //downloader.FinishDownload(false);
        //}
        //}

        /// <summary>
        /// 更新下载进度事件
        /// </summary>
        /// <param name="file"></param>
        public void Downloader_UpdateDownloadProgress(IDownloader downloader, dl_files file, int time)
        {
            if (!context.RunAsService)
            {
                //lock (DownloadServiceContext.lock_Progressing)
                //{
                downloader.ProgressBar.Dispaly(file.dl_progress,
                    file.dl_progress + "%  下载速度：" + PSDFunction.FormatByteSize(file.dl_speed) + "/s"
                    + "  已用时：" + time + "秒");
                //}
            }
            //else
            //{
            //    //context.Logger.Log(file.file_name + " - 下载进度：" + file.dl_progress + "%  下载速度：" + PSDFunction.FormatByteSize(file.dl_speed) + "/s"
            //           // + "  已用时：" + time + "秒");
            //}


            OnUpdateDownloadProgress?.Invoke(downloader, file, time);
        }

        /// <summary>
        ///下载成功事件
        /// </summary>
        /// <param name="file"></param>
        public void Downloader_FileDownloadSuccess(IDownloader downloader, dl_files file)
        {
            try
            {
                if (context.RunAsService)
                {
                    context.Logger.Log("文件下载成功：" + file.file_name);
                }
                else
                {
                    //lock (DownloadServiceContext.lock_Progressing)
                    //{
                    downloader.ProgressBar.Dispaly(file.dl_progress,
                        "下载成功 - 下载速度：" + PSDFunction.FormatByteSize(file.dl_speed) + "/s"
                        + "  已用时：" + (file.dl_end_time.Value - file.dl_start_time.Value).TotalSeconds + "秒"
                        + "  文件大小：" + PSDFunction.FormatByteSize(file.file_size));
                    //}
                }

                bool success = true;

                if (context.Device.storage_type == 0)
                {
                    success = CopyToBackupStorage(file);
                }

                if (success)
                {
                    var ret = HttpHelper.Post<HResult>(AppSettings.Setting.API.DownloadSuccess, JsonConvert.SerializeObject(file));

                    if (!ret.success)
                    {
                        context.LocalDataManager.AddFile(file);
                    }

                    DownloadingFiles.Remove(file);

                    OnFileDownloadSuccess?.Invoke(downloader, file);

                    if (Convert.ToInt32(ret.data) == Convert.ToInt32(DownloadFileState.SuccessAndFinish))
                    {
                        var task = DownloadTaskList.Where(t => t.Task.id == file.dl_task_id).FirstOrDefault();

                        if (task != null && task.Task.task_type == Convert.ToInt32(DownloadTaskCreateType.常规Routine))
                        {
                            context.CaseLogManager.DownloadImmediate();
                        }
                    }
                }
                else
                {
                    file.state = 2;
                    file.error_log = "文件复制到备存失败";
                    Downloader_FileDownloadFail(downloader, file);
                    return;
                }

            }
            catch (Exception ex)
            {
                context.Logger.Error("Downloader_FileDownloadSuccess " + ex.Message);
            }
            finally
            {
                RemoveDownloader(file);

                if (context.Closing)
                {
                    context.Running = false;
                    context.Downloading = false;
                }
            }
        }

        private bool CopyToBackupStorage(dl_files file)
        {
            bool success = false;

            string srcFile = "";
            string destPath = "";
            string destFile = "";
            try
            {
                var currMainStorage = context.Device.StorageList.Where(t => t.storage_type == 0 && t.state == 1).FirstOrDefault();

                if (currMainStorage != null)
                {
                    var currBackupStorage = context.Device.StorageList.Where(t => t.storage_type == 1 && t.storage_group == currMainStorage.storage_group).FirstOrDefault();

                    if (currBackupStorage != null)
                    {
                        srcFile = System.IO.Path.Combine(file.file_path, file.file_name);
                        destPath = file.file_path.Replace(currMainStorage.storage_driver, currBackupStorage.storage_driver);
                        destFile = System.IO.Path.Combine(destPath, file.file_name);

                        if (!System.IO.Directory.Exists(destPath))
                        {
                            System.IO.Directory.CreateDirectory(destPath);
                        }

                        System.IO.File.Copy(srcFile, destFile, true);

                        context.Logger.Log("复制文件到备存成功：" + destFile);

                        success = true;
                    }
                    else
                    {
                        context.Logger.Error("复制文件到备存出错：未找到可用的备存信息。" + "srcFile=" + System.IO.Path.Combine(file.file_path, file.file_name));
                    }
                }
                else
                {
                    context.Logger.Error("复制文件到备存出错：未找到可用的主存信息。" + "srcFile=" + System.IO.Path.Combine(file.file_path, file.file_name));
                }
            }
            catch (Exception ex)
            {
                context.Logger.Error("复制文件到备存出错：" + ex.Message + (ex.InnerException == null ? "" : ex.InnerException.Message) + "。 src=" + srcFile + " dest=" + destFile);
            }

            return success;
        }

        /// <summary>
        /// 下载失败事件
        /// </summary>
        /// <param name="file"></param>
        public void Downloader_FileDownloadFail(IDownloader downloader, dl_files file)
        {
            try
            {
                if (context.RunAsService)
                {
                    context.Logger.Log("文件下载失败：" + file.file_name);
                }
                else
                {
                    //lock (DownloadServiceContext.lock_Progressing)
                    //{
                    downloader.ProgressBar.Dispaly(file.dl_progress, "下载失败 - " + file.error_log);
                    //}
                }

                var ret = HttpHelper.Post<HResult>(AppSettings.Setting.API.DownloadFail, JsonConvert.SerializeObject(file));

                if (!ret.success)
                {
                    context.LocalDataManager.AddFile(file);
                }

                DownloadingFiles.Remove(file);

                if (file.error_log == "获取连接Session信息")
                {
                    ReConnectDownloadServer(downloader.DownloadServer);
                }
                else
                {
                    var errorFile = new error_files()
                    {
                        file_id = file.id,
                        dl_task_id = file.dl_task_id,
                        dl_task_channel_id = file.dl_task_channel_id,
                        video_start_time = file.video_start_time,
                        video_end_time = file.video_end_time,
                        dl_start_time = file.dl_start_time.Value,
                        file_name = file.file_name,
                        error_time = DateTime.Now,
                        error_log = file.error_log,
                        state = 2
                    };

                    context.ErrorFileManager.AddErrorFile(errorFile);
                }

                OnFileDownloadFail?.Invoke(downloader, file);
            }
            catch (Exception ex)
            {
                context.Logger.Error("Downloader_FileDownloadFail " + ex.Message);
            }
            finally
            {
                RemoveDownloader(file);

                if (context.Closing)
                {
                    context.Running = false;
                    context.Downloading = false;
                }
            }
        }

        private void ReConnectDownloadServer(IDownloadServer server)
        {
            context.Logger.Log("下载服务器Session过期，尝试自动重新启动服务");

            //context.ClientContext.RestartService();

            StopDownload();

            if (server.ReLogin())
            {
                context.Logger.Log("自动重新登录下载服务器成功");

                StartDownload();
            }
            else
            {
                context.Logger.Error("自动重新登录下载服务器失败：" + server.GetLastError());

                int waitMins = 5;

                context.Logger.Log($"等待{waitMins}分钟后重试");

                Thread.Sleep(1000 * 60 * 5);

                ReConnectDownloadServer(server);
            }
        }

        /// <summary>
        /// 移除下载器
        /// </summary>
        /// <param name="file"></param>
        private void RemoveDownloader(dl_files file)
        {
            lock (lock_DownloaderList)
            {
                var downloader = DownloaderList.Where(t => t.Id == file.id).FirstOrDefault();

                if (downloader != null)
                {
                    //context.Logger.Log("移除下载进程：" + downloader.FileInfo.file_name);

                    DownloaderList.Remove(downloader);

                    downloaderCount -= 1;

                    if (downloaderCount < 0)
                    {
                        downloaderCount = 0;
                    }
                }

                Thread.Sleep(2000);
            }
        }


        #region set download state
        //public HResult StartDownloadTask(string taskId)
        //{
        //    Dictionary<string, string> data = new Dictionary<string, string>();
        //    data.Add("taskId", taskId);
        //    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.StartDownloadTask, data);

        //    if (result.success)
        //    {
        //        OnDownloadTaskStateChanged?.Invoke(taskId, 1);
        //    }

        //    return result;
        //}

        //public HResult StopDownloadTask(string taskId)
        //{
        //    Dictionary<string, string> data = new Dictionary<string, string>();
        //    data.Add("taskId", taskId);
        //    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.StopDownloadTask, data);

        //    if (result.success)
        //    {
        //        OnDownloadTaskStateChanged?.Invoke(taskId, 0);
        //    }

        //    return result;
        //}

        //public HResult FinishDownloadTask(string taskId)
        //{
        //    Dictionary<string, string> data = new Dictionary<string, string>();
        //    data.Add("taskId", taskId);
        //    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.FinishDownloadTask, data);

        //    if (result.success)
        //    {
        //        OnDownloadTaskStateChanged?.Invoke(taskId, 2);

        //    }
        //    return result;
        //}

        //public HResult RestartDownloadTask(string taskId)
        //{
        //    Dictionary<string, string> data = new Dictionary<string, string>();
        //    data.Add("taskId", taskId);
        //    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.RestartDownloadTask, data);

        //    //if (result.success)
        //    //{
        //    //    OnDownloadTaskStateChanged?.Invoke(taskId, 1);
        //    //}
        //    return result;
        //}

        //public HResult StartDownloadChannel(string channelId)
        //{
        //    Dictionary<string, string> data = new Dictionary<string, string>();
        //    data.Add("channelId", channelId);
        //    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.StartDownloadChannel, data);

        //    if (result.success)
        //    {
        //        OnDownloadChannelStateChanged?.Invoke(channelId, 1);
        //    }

        //    return result;
        //}

        //public HResult StopDownloadChannel(string channelId)
        //{
        //    Dictionary<string, string> data = new Dictionary<string, string>();
        //    data.Add("channelId", channelId);
        //    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.StopDownloadChannel, data);

        //    if (result.success)
        //    {
        //        OnDownloadChannelStateChanged?.Invoke(channelId, 0);
        //    }

        //    return result;
        //}

        //public HResult FinishDownloadChannel(string channelId)
        //{
        //    Dictionary<string, string> data = new Dictionary<string, string>();
        //    data.Add("channelId", channelId);
        //    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.FinishDownloadChannel, data);

        //    if (result.success)
        //    {
        //        OnDownloadChannelStateChanged?.Invoke(channelId, 2);
        //    }

        //    return result;
        //}

        //public HResult RestartDownloadChannel(string channelId)
        //{
        //    Dictionary<string, string> data = new Dictionary<string, string>();
        //    data.Add("channelId", channelId);
        //    var result = HttpHelper.Post<HResult>(AppSettings.Setting.API.RestartDownloadChannel, data);

        //    //if (result.success)
        //    //{
        //    //    OnDownloadChannelStateChanged?.Invoke(channelId, 1);
        //    //}

        //    return result;
        //}

        #endregion
    }
}
